﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace BEELab
{
    public partial class EditExperiment : System.Web.UI.Page
    {
        /// <summary>
        /// Validates the correction of all stage names belongs to the experiment 
        /// </summary>
        private void SetStageNameValidation()
        {
            string Names = BEELab.Logic.ProgramManagement.StageManagement.StageManagement.EnumerateStagesForProgram(int.Parse(Request.QueryString["ID"].ToString()), "|");
            if (Names.Length > 0)
            {
                StageRegularExpressionValidator.ValidationExpression = "^(?!" + Names + ").*$";
            }
            else
            {
                StageRegularExpressionValidator.ValidationExpression = ".*";
            }
        }

        /// <summary>
        /// Occures on every page load - first time or post back
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["ID"] == null)
            {
                Response.Redirect("Main.aspx");
            }

            if (Request.QueryString["ID"] != null && Session["UserID"] != null && BEELab.Logic.ProgramManagement.ExperimentManagement.GetOwnerID(int.Parse(Request.QueryString["ID"].ToString())) != int.Parse(Session["UserID"].ToString()) && (Session["Admin"] == null || (bool)Session["Admin"] == false))
            {
                Response.Redirect("Main.aspx");
            }

            if (!IsPostBack)
            {
                string varNames = BEELab.Logic.ProgramManagement.VariableManagement.VariableManagement.EnumerateVariablesForProgram(int.Parse(Request.QueryString["ID"].ToString()), "|");
                if (varNames.Length > 0)
                {
                    RegexValidator2.ValidationExpression = "^(?!" + varNames + ").*$";
                }
                else
                {
                    RegexValidator2.ValidationExpression = ".*";
                }

                SetStageNameValidation();

                txtName.Text = BEELab.Logic.ProgramManagement.ExperimentManagement.GetName(Convert.ToInt32(Request.QueryString["ID"]));
                txtDescription.Text = BEELab.Logic.ProgramManagement.ExperimentManagement.GetDescription(Convert.ToInt32(Request.QueryString["ID"]));

                try
                {
                    string firstStage = BEELab.Logic.ProgramManagement.StageManagement.StageManagement.GetFirstStage(Request.QueryString["ID"]);
                    if (firstStage == null || firstStage.Equals(""))
                        firstStage = BEELab.Logic.ProgramManagement.StageManagement.StageManagement.setDefaultFirstStage(Request.QueryString["ID"]);
                    ddlStage.SelectedValue = firstStage;
                    //TODO: Need to check here if ddlStage.Items.Contains(new ListItem (firstStage))
                    //but not alwayws working. it will be ok if once we remove stage we take care of it as well
                }
                catch (Exception) { }
            }
        }

        /// <summary>
        /// Occures when deleting a stage that belongs to current experiment.
        /// Function will be deleted from DB an GUI will be updated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void gvStage_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            BEELab.Logic.ProgramManagement.StageManagement.StageManagement.DeleteStage(Convert.ToInt32(gvStage.DataKeys[e.RowIndex].Value),Request.QueryString["ID"]);
            ddlStage.DataBind();
            gvVariable.DataBind();
            SetStageNameValidation();
            ddlStage.SelectedValue = BEELab.Logic.ProgramManagement.StageManagement.StageManagement.GetFirstStage(Request.QueryString["ID"]); ;
        }

        /// <summary>
        /// Occures when deleting session that belongs to current experiment.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void gvSession_RowDeleting(object sender, GridViewDeleteEventArgs e)
        {
            int SessionID = Convert.ToInt32(gvStage.DataKeys[e.RowIndex].Value);

            BEELab.Logic.ProgramManagement.SessionManagement.SessionManagement.DeleteSession(SessionID);

            if (Global.BlockElementsDictionary.ContainsKey(SessionID))
                Global.BlockElementsDictionary.Remove(SessionID);

            if (Global.PresentationElementsDictionary.ContainsKey(SessionID))
                Global.PresentationElementsDictionary.Remove(SessionID);

            if (Global.DataElementsDictionary.ContainsKey(SessionID))
                Global.DataElementsDictionary.Remove(SessionID);

            if (Global.VariableIDNameDictionary.ContainsKey(SessionID))
                Global.VariableIDNameDictionary.Remove(SessionID);

            if (Global.SessionVariables.ContainsKey(SessionID))
                Global.SessionVariables.Remove(SessionID);

            if (Global.VariableScopeDictionary.ContainsKey(SessionID))
                Global.VariableScopeDictionary.Remove(SessionID);

            foreach (string subject in BEELab.Logic.ProgramManagement.SessionManagement.SessionManagement.GetSubjectList(SessionID))
            {
                if (Global.MessageBox.ContainsKey(subject))
                {
                    Global.MessageBox.Remove(subject);
                }

                if (Global.SubjectConnetionDictionary.ContainsKey(subject))
                {
                    Global.SubjectConnetionDictionary.Remove(subject);
                }

                if (Global.SubjectVariables.ContainsKey(subject))
                {
                    Global.SubjectVariables.Remove(subject);
                }
            }
        }

        /// <summary>
        /// Occures once adding a new stage to current experiment.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button1_Click(object sender, EventArgs e)
        {
            TextBox1.Text = TextBox1.Text.Replace("'", "").Replace("\"", "");
            int id = BEELab.Logic.ProgramManagement.StageManagement.StageManagement.CreateStage(int.Parse(Request.QueryString["ID"]), TextBox1.Text, TextBox2.Text, true, true, true);
            BEELab.Logic.ProgramManagement.StageManagement.PresentationElements.CreateElement(id, Properties.Settings.Default.PresentationLayer + id, "Presetation Layer", "Your Presentation Layer");
            TextBox1.Text = "";
            TextBox2.Text = "";
            gvStage.DataBind();
            ddlStage.DataBind();
            SetStageNameValidation();
            if (BEELab.Logic.ProgramManagement.StageManagement.StageManagement.GetStagesList(Request.QueryString["ID"]).Count() == 1)
                BEELab.Logic.ProgramManagement.StageManagement.StageManagement.setDefaultFirstStage(Request.QueryString["ID"]);
            ddlStage.SelectedValue = BEELab.Logic.ProgramManagement.StageManagement.StageManagement.GetFirstStage(Request.QueryString["ID"]);
        }

        /// <summary>
        /// Occures once adding a new variable to current experiment.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button2_Click(object sender, EventArgs e)
        {
            BEELab.Logic.ProgramManagement.VariableManagement.VariableManagement.CreateVariable(int.Parse(Request.QueryString["ID"]), TextBox3.Text, TextBox4.Text, txtDefaultValue.Text, rblScope.Text);
            TextBox3.Text = "";
            TextBox4.Text = "";
            txtDefaultValue.Text = "";
            rblScope.ClearSelection();
            gvVariable.DataBind();
        }

        /// <summary>
        /// Occures once creating new session to current experiment.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button3_Click(object sender, EventArgs e)
        {
            BEELab.Logic.ProgramManagement.SessionManagement.SessionManagement.CreateSession(int.Parse(Request.QueryString["ID"]), TextBox5.Text, TextBox6.Text);
            TextBox5.Text = "";
            TextBox6.Text = "";

            gvSession.DataBind();
        }

        /// <summary>
        /// Occures when updating durrent experiment details
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnSubmit_Click(object sender, EventArgs e)
        {
            BEELab.Logic.ProgramManagement.ExperimentManagement.UpdateExperiment(int.Parse(Request.QueryString["ID"].ToString()), txtName.Text, txtDescription.Text, int.Parse(Session["UserID"].ToString()), true);
        }

        /// <summary>
        /// Updating experiment first stage on DB
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Button4_Click(object sender, EventArgs e)
        {
            BEELab.Logic.ProgramManagement.StageManagement.StageManagement.SetFirstStage(int.Parse(Request.QueryString["ID"].ToString()), ddlStage.SelectedItem.Text);
        }

        /// <summary>
        /// Occures once first stage sekection is changing. Will update first stage on GUI and on DB. 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void ddlStage_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                String stageName = ddlStage.SelectedValue;
                String progID = Request.QueryString["ID"];
                int programID;
                if (progID != null)
                {
                    programID = Convert.ToInt32(progID);
                    //Set to experiment new first stage to the selected value
                    Boolean res = BEELab.Logic.ProgramManagement.StageManagement.StageManagement.SetFirstStage(programID, stageName);
                }
            }
            catch (Exception) { }
        }
    }
}